/*
 * A unit test and example of how to use the simple C hashmap
 */

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <sys/time.h>
#include <stdint.h>
#include <string.h>
#include "hashmap.h"
#include "list.h"

#define KEY_MAX_LENGTH (256)
#define KEY_PREFIX ("somekey")
#define KEY_COUNT (300)

typedef struct data_struct_s
{
    char key_string[KEY_MAX_LENGTH];
    int number;
} data_struct_t;

typedef struct{
    char key_buf[KEY_MAX_LENGTH];
    int value;
    struct slist_s list;
} data_list_node_t;

struct slist_s g_data_list_head;

int main(char* argv, int argc)
{
    int index, i;
    int error;
    map_t mymap;
    char key_string[KEY_MAX_LENGTH];
    data_struct_t* value;

    data_list_node_t *node = NULL;

    struct timeval tv1, tv2;
    uint64_t t1, t2;

    mymap = hashmap_new();

    slist_init(&g_data_list_head);

    /* First, populate the hash map with ascending values */
    for (index=0; index<KEY_COUNT; index+=1){
        /* Store the key string along side the numerical value so we can free it later */
        value = malloc(sizeof(data_struct_t));
        snprintf(value->key_string, KEY_MAX_LENGTH, "%s%d", KEY_PREFIX, index);
        value->number = index;
        error = hashmap_put(mymap, value->key_string, value);
        assert(error==MAP_OK);

        // list node add
        node = (data_list_node_t *)malloc(sizeof(data_list_node_t));
        memset(node, 0, sizeof(data_list_node_t));
        slist_init(&node->list);

        snprintf(node->key_buf, KEY_MAX_LENGTH, "%s%d", KEY_PREFIX, index);
        node->value = index;

        slist_add_tail(&node->list, &g_data_list_head);
    }

    /* Now, check all of the expected values are there */
    gettimeofday(&tv1, NULL);
    for (index=0; index<KEY_COUNT; index+=1){
        snprintf(key_string, KEY_MAX_LENGTH, "%s%d", KEY_PREFIX, index);
        error = hashmap_get(mymap, key_string, (void**)(&value));
        
        /* Make sure the value was both found and the correct number */
        assert(error==MAP_OK);
        assert(value->number==index);
	
	    //printf("get key:%s, value:%d\n", value->key_string, value->number);

    }
    gettimeofday(&tv2, NULL);
    t1 = (uint64_t)tv1.tv_sec * 1000000 + tv1.tv_usec;
    t2 = (uint64_t)tv2.tv_sec * 1000000 + tv2.tv_usec;
    printf("hash map iterate cost time %ld us\n", t2 - t1);


    gettimeofday(&tv1, NULL);
    for(i = 0; i < KEY_COUNT; i++){
        snprintf(key_string, KEY_MAX_LENGTH, "%s%d", KEY_PREFIX, i);
        slist_for_each_entry(&g_data_list_head, node, data_list_node_t, list){
            if(0 == strcmp(node->key_buf, key_string)){
          //      printf("find %s ok, value=%d\n", node->key_buf, node->value);
                break;
            }
        }

    }
    gettimeofday(&tv2, NULL);
    t1 = (uint64_t)tv1.tv_sec * 1000000 + tv1.tv_usec;
    t2 = (uint64_t)tv2.tv_sec * 1000000 + tv2.tv_usec;
    printf("list iterate cost time %ld us\n", t2 - t1);
 
    /* Now, destroy the map */
    hashmap_free(mymap);

    return 1;
}
